package com.hardson.toolkit.listsort;

import com.hardson.toolkit.util.ReflectUtil;

import java.text.Collator;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

public class ListSorter<T> implements Comparator<T> {

    public enum SortOrder {
        ASC, // 顺序
        DESC, // 倒序
        UNSORTED// 不排序
    }

    /**
     * 中文按拼音排序
     */
    public final static Comparator<Object> CHINA_COMPARE = Collator.getInstance(Locale.CHINA);

    private final SortOrder order;// 顺序或倒序，默认为顺序

    private String colName = "";// 被比较的属性名称

    private boolean pinyinSort;

    private ListSorter(final String colName, final SortOrder order, final boolean pinyinSort) {
        this.order = order;
        this.colName = colName;
        this.pinyinSort = pinyinSort;
    }

    /**
     * 比较器的比较方法
     */
    @SuppressWarnings("unchecked")
    @Override
    public int compare(final T t0, final T t1) {
        T[] swapObj = this.swap(t0, t1);
        Object val0;
        Object val1;
        try {
            val0 = ReflectUtil.invokeGet(swapObj[0], this.colName);
            val1 = ReflectUtil.invokeGet(swapObj[1], this.colName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Integer result = this.compareNull(val0, val1);
        if (result != null) {
            return result;
        }
        Comparable<Comparable<T>> cmp0 = (Comparable<Comparable<T>>) val0;
        Comparable<T> cmp1 = (Comparable<T>) val1;
        if (this.pinyinSort) {
            return CHINA_COMPARE.compare(cmp0, cmp1);
        }
        return cmp0.compareTo(cmp1);
    }

    private Integer compareNull(Object val0, Object val1) {
        if (val0 == null && val1 == null) {
            return 0;
        }
        // 数据型的对象，如果为空则以0比较，因为0的数学意义即为空
        if (val0 instanceof Number || val1 instanceof Number) {
            if (val0 == null) {
                val0 = new Double(0);
            }
            if (val1 == null) {
                val1 = new Double(0);
            }
            return null;
        }
        if (val0 == null) {
            return -1;
        }
        if (val1 == null) {
            return 1;
        }
        return null;
    }

    /**
     * 交换两个对象，用于控制升序或降序
     *
     * @param t1 要交换的范型对象1
     * @param t2 要交换的范型对象2
     * @return T[]
     */
    protected T[] swap(T t1, T t2) {
        if (this.order == SortOrder.DESC) {
            T oTmp = t1;
            t1 = t2;
            t2 = oTmp;
        }
        @SuppressWarnings("unchecked")
        T[] t = (T[]) new Object[]{t1, t2};
        return t;
    }

    public static <T> void sort(final List<T> dataList, final String colName) {
        sort(dataList, colName, SortOrder.ASC, false);
    }

    public static <T> void sort(final List<T> dataList, final String colName,
                                final SortOrder order) {
        sort(dataList, colName, order, false);
    }

    public static <T> void sort(final List<T> dataList, final String colName,
                                final boolean pinyinSort) {
        sort(dataList, colName, SortOrder.ASC, pinyinSort);
    }

    public static <T> void sort(final List<T> dataList, final String colName,
                                final SortOrder order, final boolean pinyinSort) {
        dataList.sort(ListSorter.of(colName, order, pinyinSort));
    }

    private static <T> ListSorter<T> of(final String colName, final SortOrder order,
                                        final boolean pinyinSort) {
        return new ListSorter<T>(colName, order, pinyinSort);
    }
}
